﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Globalization;
using UIT._2D;
using System.Windows.Markup;

namespace UIT.Converters
{
    /// <summary>Converts instances of other types to and from a <see cref="T:System.Windows.Media.Matrix" />. </summary>
    public sealed class MatrixConverter : TypeConverter
    {
        /// <summary>Determines whether an object can be converted from a specific type to an instance of a <see cref="T:System.Windows.Media.Matrix" />.  </summary>
        /// <returns>true if the type can be converted to a <see cref="T:System.Windows.Media.Matrix" />; otherwise, false.</returns>
        /// <param name="context">The context information of a type.</param>
        /// <param name="sourceType">The type of the source that is being evaluated for conversion.</param>
        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
        }
        /// <summary>Determines whether an instance of a <see cref="T:System.Windows.Media.Matrix" /> can be converted to a different type. </summary>
        /// <returns>true if this <see cref="T:System.Windows.Media.Matrix" /> can be converted to <paramref name="destinationType" />; otherwise, false.</returns>
        /// <param name="context">The context information of a type.</param>
        /// <param name="destinationType">The desired type this <see cref="T:System.Windows.Media.Matrix" /> is being evaluated for conversion.</param>
        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            return destinationType == typeof(string) || base.CanConvertTo(context, destinationType);
        }
        /// <summary>Attempts to convert the specified object to a <see cref="T:System.Windows.Media.Matrix" />. </summary>
        /// <returns>The <see cref="T:System.Windows.Media.Matrix" /> created from converting <paramref name="value" />.</returns>
        /// <param name="context">The context information of a type.</param>
        /// <param name="culture">The <see cref="T:System.Globalization.CultureInfo" /> of the type being converted.</param>
        /// <param name="value">The object being converted.</param>
        /// <exception cref="T:System.NotSupportedException">The specified object is null or is a type that cannot be converted to a <see cref="T:System.Windows.Media.Matrix" />.</exception>
        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
		{

#if !SILVERLIGHT
			if (value == null)
            {
                throw base.GetConvertFromException(value);
            }
#endif
            string text = value as string;
            if (text != null)
            {
                return Matrix.Parse(text);
            }
            return base.ConvertFrom(context, culture, value);
        }
        /// <summary>Attempts to convert a <see cref="T:System.Windows.Media.Matrix" /> to a specified type. </summary>
        /// <returns>The object created from converting this <see cref="T:System.Windows.Media.Matrix" />.</returns>
        /// <param name="context">The context information of a type.</param>
        /// <param name="culture">The <see cref="T:System.Globalization.CultureInfo" /> of the type being converted.</param>
        /// <param name="value">The <see cref="T:System.Windows.Media.Matrix" /> to convert.</param>
        /// <param name="destinationType">The type to convert this <see cref="T:System.Windows.Media.Matrix" /> to.</param>
        /// <exception cref="T:System.NotSupportedException">The <paramref name="value" /> is null or is not a <see cref="T:System.Windows.Media.Matrix" />, or the <paramref name="destinationType" /> is not a valid conversion type.</exception>
        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
        {
            if (destinationType != null && value is Matrix)
            {
                Matrix matrix = (Matrix)value;
                if (destinationType == typeof(string))
                {
                    return matrix.ConvertToString(null, culture);
                }
            }
            return base.ConvertTo(context, culture, value, destinationType);
        }
        /// <summary>Initializes a new instance of <see cref="T:System.Windows.Media.MatrixConverter" />.</summary>
        public MatrixConverter()
        {
        }
    }


#if !SILVERLIGHT
    /// <summary>Converts instances of <see cref="T:System.String" /> to and from instances of <see cref="T:System.Windows.Media.Matrix" />.</summary>
    public class MatrixValueSerializer : ValueSerializer
    {
        /// <summary>Determines if conversion from a given <see cref="T:System.String" /> to an instance of <see cref="T:System.Windows.Media.Matrix" /> is possible.</summary>
        /// <returns>true if the value can be converted; otherwise, false.</returns>
        /// <param name="value">String to evaluate for conversion.</param>
        /// <param name="context">Context information used for conversion.</param>
        public override bool CanConvertFromString(string value, IValueSerializerContext context)
        {
            return true;
        }
        /// <summary>Determines if an instance of <see cref="T:System.Windows.Media.Matrix" /> can be converted to a <see cref="T:System.String" />.</summary>
        /// <returns>true if <paramref name="value" /> can be converted into a <see cref="T:System.String" />; otherwise, false.</returns>
        /// <param name="value">Instance of <see cref="T:System.Windows.Media.Matrix" /> to evaluate for conversion.</param>
        /// <param name="context">Context information used for conversion.</param>
        /// <exception cref="T:System.ArgumentException">Occurs when <paramref name="value" /> is not a <see cref="T:System.Windows.Media.Int32Collection" />.</exception>
        public override bool CanConvertToString(object value, IValueSerializerContext context)
        {
            return value is Matrix;
        }
        /// <summary>Converts a <see cref="T:System.String" /> into a <see cref="T:System.Windows.Media.Matrix" />.</summary>
        /// <returns>A new instance of <see cref="T:System.Windows.Media.Matrix" /> based on the supplied <paramref name="value" />.</returns>
        /// <param name="value">
        ///   <see cref="T:System.String" /> value to convert into a <see cref="T:System.Windows.Media.Matrix" />.</param>
        /// <param name="context">Context information used for conversion.</param>
        public override object ConvertFromString(string value, IValueSerializerContext context)
        {
            if (value != null)
            {
                return Matrix.Parse(value);
            }
            return base.ConvertFromString(value, context);
        }
        /// <summary>Converts an instance of <see cref="T:System.Windows.Media.Matrix" /> to a <see cref="T:System.String" />.</summary>
        /// <returns>A <see cref="T:System.String" /> representation of the supplied <see cref="T:System.Windows.Media.Matrix" /> object.</returns>
        /// <param name="value">Instance of <see cref="T:System.Windows.Media.Matrix" /> to evaluate for conversion.</param>
        /// <param name="context">Context information used for conversion.</param>
        public override string ConvertToString(object value, IValueSerializerContext context)
        {
            if (value is Matrix)
            {
                return ((Matrix)value).ConvertToString(null, CultureInfo.InvariantCulture);
            }
            return base.ConvertToString(value, context);
        }
        /// <summary>Initializes a new instance of the <see cref="T:System.Windows.Media.Converters.MatrixValueSerializer" /> class.</summary>
        public MatrixValueSerializer()
        {
        }
    }
#endif
}
